using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Acms.SqlDal;

namespace Acms.Bll
{
    public class User : BaseItem
    {
        public enum Genders : byte
        {
            Unknown = 0,
            Male = 1,
            Female = 2
        }

        protected User() : base() { }
        protected User(Hashtable table) : base(table) { }
        private User(Hashtable table, List<User> collection) : base(table, collection) { }
        protected User(Hashtable table, ICollection collection) : base(table, collection) { }

        protected override Base CreateDal()
        {
            return new UserDal();
        }
        
        public static User CreateInstance()
        {
            return new User();
        }

        protected override void Load(Hashtable table)
        {
            id = (int)table[UserDal.Fields.Id];
            siteId = (int)table[UserDal.Fields.SiteId];
            userName = (string)table[UserDal.Fields.UserName];
            firstName = (string)table[UserDal.Fields.FirstName];
            lastName = (string)table[UserDal.Fields.LastName];
            dateOfBirth = (DateTime)table[UserDal.Fields.DateOfBirth];
            emailAddress = (string)table[UserDal.Fields.EmailAddress];
            gender = (byte)table[UserDal.Fields.Gender];
            address1 = (string)table[UserDal.Fields.Address1];
            address2 = (string)table[UserDal.Fields.Address2];
            town = (string)table[UserDal.Fields.Town];
            postCode = (string)table[UserDal.Fields.PostCode];
            mobileTel = (string)table[UserDal.Fields.MobileTel];
            created = (DateTime)table[UserDal.Fields.Created];
        }

        protected int id;
        public int Id
        {
            get { return id; }
        }

        protected int siteId;
        public int SiteId
        {
            get { return siteId; }
        }


        protected string userName;
        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }

        protected string firstName;
        public string FirstName
        {
            get{ return firstName;}
            set { firstName = value;}
        }

        protected string lastName;
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }

        public string DisplayName
        {
            get
            {
                string tmp = string.Format("{0} {1}", firstName, lastName);
                tmp = tmp.Trim();
                while(tmp.Contains("  "))
                {
                    tmp = tmp.Replace("  ", " ");
                }
                return tmp;
            }
        }

        protected DateTime dateOfBirth;
        public DateTime DateOfBirth
        {
            get { return dateOfBirth; }
            set { dateOfBirth = value; }
        }

        protected string emailAddress;
        public string EmailAddress
        {
            get { return emailAddress; }
            set { emailAddress = value; }
        }

        protected byte gender;
        public Genders Gender
        {
            get { return (Genders)gender; }
            set { gender = (byte)value; }
        }

        protected string address1;
	    public string Address1
	    {
		    get { return address1;}
		    set { address1 = value;}
	    }

        protected string address2;
        public string Address2
        {
            get { return address2; }
            set { address2 = value; }
        }

        protected string town;
        public string Town
        {
            get { return town; }
            set { town = value; }
        }

        protected string postCode;
        public string PostCode
        {
            get { return postCode; }
            set { postCode = value; }
        }

        protected string mobileTel;
        public string MobileTel
        {
            get { return mobileTel; }
            set { mobileTel = value; }
        }

        protected DateTime created;
        public DateTime Created
        {
            get { return created; }
        }

        public int Age
        {
            get { return AgeAt(DateTime.Now); }
        }

        public int AgeAt(DateTime dateTime)
        {
            int val = 0;
            if (DateOfBirth != DateTime.MinValue)
            {
                val = dateTime.Year - DateOfBirth.Year;
                if (dateTime.Month < DateOfBirth.Month || (dateTime.Month == DateOfBirth.Month && dateTime.Day < DateOfBirth.Day))
                {
                    val--;
                }
            }
            return val;
        }

        private static User Get(Hashtable table)
        {
            if (table != null)
                return new User(table);
            else
                return null;
        }

        private static List<User> Get(Hashtable[] tables)
        {
            if (tables != null)
            {
                List<User> tmp = new List<User>();
                foreach (Hashtable table in tables)
                {
                    tmp.Add(new User(table, tmp));
                }
                return tmp;
            }
            else
                return null;
        }
        
        public static User GetById(int id)
        {
            UserDal dal = new UserDal();
            return Get(dal.GetById(id));
        }

        public static User GetByUserName(string userName, int siteId)
        {
            UserDal dal = new UserDal();
            return Get(dal.GetByUserName(userName, siteId));
        }

        public static User GetByEmailAddress(string emailAddress, int siteId)
        {
            UserDal dal = new UserDal();
            return Get(dal.GetByEmailAddress(emailAddress, siteId));
        }

        internal static User GetFromLoginKey(Guid key)
        {
            UserDal dal = new UserDal();
            return Get(dal.GetFromLoginKey(key, DateTime.Now));
        }

        internal void DeleteLoginKey(Guid key)
        {
            UserDal dal = new UserDal();
            dal.DeleteLoginKey(key, this.id);
        }

        protected bool CustomPropertiesLoaded
        {
            get { return customProperties != null; }
        }
        private List<UserCustomProperty> customProperties;
        protected List<UserCustomProperty> CustomProperties
        {
            get 
            {
                if (customProperties == null)
                {
                    customProperties = UserCustomProperty.GetAllByUserId(id);
                }
                return customProperties;
            }
        }

        public string GetCustomProperty(string key)
        {
            if (key != null && CustomProperties != null)
            {
                foreach (UserCustomProperty p in CustomProperties)
                {
                    if (p.Name != null && p.Name.ToLower() == key.ToLower())
                    {
                        return p.Value;
                    }
                }
            }
            return null;
        }

        public void SetCustomProperty(string key, string value)
        {
            if (key != null)
            {
                if (CustomProperties == null)
                {
                    customProperties = new List<UserCustomProperty>();
                }

                bool found = false;
                foreach (UserCustomProperty p in CustomProperties)
                {
                    if (p.Name != null && p.Name.ToLower() == key.ToLower())
                    {
                        p.Value = value;
                        found = true;
                    }
                }
                if (!found)
                {
                    customProperties.Add(UserCustomProperty.CreateInstance(id, key ,value));
                }
            }
        }
        
    }
}
